/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.taglib.core.functions;

import com.blandware.atleap.common.util.ConvertUtil;

import java.lang.reflect.Method;
import java.util.List;

/**
 * <p>Contains set of functions to ease the work with collection on the JSP</p>
 * <p><a href="CollectionFunctions.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.5 $ $Date: 2006/08/03 10:08:15 $
 */
public class CollectionFunctions {

	/**
	 * Calculates size of argument. Supported types are ones, supported by <code>ConvertUtil.convertCollectionToList(java.lang.Object)</code>.
	 * In addition, you may provide <code>getSize()</code> or <code>getLength()</code> method in object's class which return type
	 * must be either <code>int</code> or </code>java.lang.Integer</code>.
	 * If none of conditions are met, <code>java.lang.IllegalArgumentException</code> will be thrown
	 *
	 * @param o Object to calculate the size of
	 * @return Size of object according to rules, specified above
	 * @throws IllegalArgumentException if argument does not met rules, specified in
	 *                                  <code>ConvertUtil.convertCollectionToList(java.lang.Object)</code>
	 *                                  and does not provide no-argument <code>getSize()</code>
	 *                                  or <code>getLength()</code> method or return type of this method
	 *                                  is not <code>int</code> nor </code>java.lang.Integer</code>
	 * @see com.blandware.atleap.common.util.ConvertUtil#convertCollectionToList(java.lang.Object)
	 */
	public static Integer sizeOf(Object o) {
		int size = 0;
		if ( o != null ) {
			boolean sizeAcquired = false;
			// convert specified collection to list
			try {
				List list = ConvertUtil.convertCollectionToList(o);
				size = list.size();
				sizeAcquired = true;
			} catch ( IllegalArgumentException e ) {
				// object is not convertable to list
			}
			if ( !sizeAcquired ) {
				// look for getSize() or getLength() method
				Method sizeMethod = null;
				try {
					sizeMethod = o.getClass().getMethod("getSize", new Class[0]);
				} catch ( NoSuchMethodException e ) {
					// ignore
				}

				if ( sizeMethod == null ) {
					try {
						sizeMethod = o.getClass().getMethod("getLength", new Class[0]);
					} catch ( NoSuchMethodException e ) {
						// ignore again
					}
				}

				if ( sizeMethod != null ) {
					// if method has been found, invoke it on specified object
					try {
						Integer oSize = (Integer) sizeMethod.invoke(o, (Object[]) null);
						size = oSize.intValue();
					} catch ( Exception e ) {
						throw new IllegalArgumentException(e.getClass().getName() + ": " + e.getMessage());
					}
				} else {

				}
			}
		}
		return new Integer(size);
	}


	/**
	 * Constructor is private, because this class contains static methods only
	 */
	private CollectionFunctions() {
	}


}
